#include "common.h"

void print_register(char *reg_name, u32int reg_value, size_t size)
{
	monitor_write(reg_name);
	monitor_write_hex(reg_value, size);
	monitor_put('\t');
}

// Dump general purpose registers
void do_dump_registers(struct several_registers regs)
{
	print_register("EIP: ", regs.eip, 4);
	print_register("DS: ", regs.ds, 2);
	print_register("CS: ", regs.cs, 2);
	monitor_put('\n');

	print_register("EDI: ", regs.edi, 4);
	print_register("ESI: ", regs.esi, 4);
	print_register("EBP: ", regs.ebp, 4);
	print_register("ESP: ", regs.esp, 4);
	monitor_put('\n');

	print_register("EAX: ", regs.eax, 4);
	print_register("EBX: ", regs.ebx, 4);
	print_register("ECX: ", regs.ecx, 4);
	print_register("EDX: ", regs.edx, 4);
}

// Write a byte out to the specified port.
void outb(u16int port, u8int value)
{
    asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
}

u8int inb(u16int port)
{
   u8int ret;
   asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
   return ret;
}

u16int inw(u16int port)
{
   u16int ret;
   asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
   return ret;
} 

extern void panic(const char *message, const char *file, u32int line)
{
    // We encountered a massive problem and have to stop.
    asm volatile("cli"); // Disable interrupts.

    monitor_write("PANIC(");
    monitor_write(message);
    monitor_write(") at ");
    monitor_write(file);
    monitor_write(":");
    monitor_write_dec(line);
    monitor_write("\n");
    // Halt by going into an infinite loop.
    for(;;);
}

extern void panic_assert(const char *file, u32int line, const char *desc)
{
    // An assertion failed, and we have to panic.
    asm volatile("cli"); // Disable interrupts.

    monitor_write("ASSERTION-FAILED(");
    monitor_write(desc);
    monitor_write(") at ");
    monitor_write(file);
    monitor_write(":");
    monitor_write_dec(line);
    monitor_write("\n");
    // Halt by going into an infinite loop.
    for(;;);
}
